/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.*; import java.text.MessageFormat; /** The RADMenuItemComponent represents one menu item component placed on the Form. * * @author Petr Hamernik, Ian Formanek */ public class RADMenuItemComponent extends RADComponent { static final Object DUMMY_SEPARATOR_INSTANCE = new Object (); /** A JDK 1.1 serial version UID */ // static final long serialVersionUID = -6333847833552116543L; /** Type of container */ private int type; /** Possible constants for type variable */ static final int T_MENUBAR = 0x01110; static final int T_MENUITEM = 0x00011; static final int T_CHECKBOXMENUITEM = 0x00012; static final int T_MENU = 0x00113; static final int T_POPUPMENU = 0x01114; static final int T_JPOPUPMENU = 0x01125; static final int T_JMENUBAR = 0x01126; static final int T_JMENUITEM = 0x00027; static final int T_JCHECKBOXMENUITEM = 0x00028; static final int T_JMENU = 0x00129; static final int T_JRADIOBUTTONMENUITEM = 0x0002A; static final int T_SEPARATOR = 0x1001B; static final int T_JSEPARATOR = 0x1002C; /** Masks for the T_XXX constants */ static final int MASK_AWT = 0x00010; static final int MASK_SWING = 0x00020; static final int MASK_CONTAINER = 0x00100; static final int MASK_ROOT = 0x01000; static final int MASK_SEPARATOR = 0x10000; /** The MessageFormat for component names */ private static MessageFormat menuNameFormat = new MessageFormat(FormEditor.getFormBundle().getString("FMT_MenuName")); // ----------------------------------------------------------------------------- // Private properties transient private RADMenuComponent parent; /** * @associates DesignTimeMenus */ private static java.util.HashMap menusByFM = new java.util.HashMap (); // ----------------------------------------------------------------------------- // Initialization void initParent (RADMenuComponent parent) { this.parent = parent; } /** No synthetic properties for AWT Separator */ protected org.openide.nodes.Node.Property[] createSyntheticProperties () { if (type == T_SEPARATOR) return RADComponent.NO_PROPERTIES; else return super.createSyntheticProperties (); } public RADMenuComponent getParentMenu () { return parent; } // ----------------------------------------------------------------------------- // Public interface public void setComponent (Class beanClass) { type = recognizeType(beanClass); // to initialize the type before calling super.setComponent is crucial, // as the type is used in various methods called from the setComponent // (e.g. the createSyntheticProperties () relies on this order to correctly // provide no properties for AWT menu separators) super.setComponent (beanClass); Object o = getBeanInstance(); // XXX(-tdt) PopupMenu is a subclass of MenuItem !! /* if (o instanceof MenuItem) { */ if (o.getClass() == MenuItem.class) { JMenuItem designItem = ((JMenuItem) getDesignTimeMenus(getFormManager()).getDesignTime(o)); designItem.addActionListener(getDefaultActionListener()); } else if (o instanceof JMenuItem) { ((JMenuItem)o).addActionListener(getDefaultActionListener()); } } int getMenuItemType () { return type; } /** Test the given class if is is subclass of one of four basic classes and * return adequate T_XXX constant. */ static int recognizeType(Class cl) { if (JSeparator.class.isAssignableFrom(cl)) return T_JSEPARATOR; if (org.netbeans.modules.form.Separator.class.isAssignableFrom(cl)) return T_SEPARATOR; if (PopupMenu.class.isAssignableFrom(cl)) return T_POPUPMENU; if (Menu.class.isAssignableFrom(cl)) return T_MENU; if (CheckboxMenuItem.class.isAssignableFrom(cl)) return T_CHECKBOXMENUITEM; if (MenuItem.class.isAssignableFrom(cl)) return T_MENUITEM; if (MenuBar.class.isAssignableFrom(cl)) return T_MENUBAR; if (JRadioButtonMenuItem.class.isAssignableFrom(cl)) return T_JRADIOBUTTONMENUITEM; if (JMenu.class.isAssignableFrom(cl)) return T_JMENU; if (JCheckBoxMenuItem.class.isAssignableFrom(cl)) return T_JCHECKBOXMENUITEM; if (JMenuItem.class.isAssignableFrom(cl)) return T_JMENUITEM; if (JMenuBar.class.isAssignableFrom(cl)) return T_JMENUBAR; if (JPopupMenu.class.isAssignableFrom(cl)) return T_JPOPUPMENU; throw new InternalError ("Cannot create RADMenuItemComponent for nonmenu class:"+cl.getName()); // NOI18N } private ActionListener getDefaultActionListener() { return new ActionListener() { public void actionPerformed(ActionEvent ev) { if (!getFormManager ().isTestMode () && hasDefaultEvent ()) attachDefaultEvent (); } }; } static DesignTimeMenus getDesignTimeMenus (FormManager2 fm) { DesignTimeMenus dtm = (DesignTimeMenus) menusByFM.get (fm); if (dtm == null) { dtm = new DesignTimeMenus (fm); menusByFM.put (fm, dtm); } return dtm; } // to find existing menu if caller does not know about formManager public static Object findDesignTimeMenu (Object awtMenu) { Object result; for (java.util.Iterator it = menusByFM.keySet().iterator(); it.hasNext(); ) { DesignTimeMenus dtm = (DesignTimeMenus) menusByFM.get (it.next()); if ((result = dtm.getDesignTime (awtMenu)) != null) { return result; } } return null; } // ----------------------------------------------------------------------------- // Inner classes static class DesignTimeMenus { /** * @associates Object */ final java.util.HashMap designTimeMenus = new java.util.HashMap (); DesignTimeMenus (FormManager2 fm) { fm.addFormListener (new FormAdapter () { public void propertyChanged (FormPropertyEvent evt) { if (evt.getRADComponent () instanceof RADMenuItemComponent) { RADMenuItemComponent comp = (RADMenuItemComponent) evt.getRADComponent (); copyMenuProperties (comp.getBeanInstance(), getDesignTime (comp.getBeanInstance())); } } public void formLoaded () { for (java.util.Iterator it = designTimeMenus.keySet().iterator(); it.hasNext(); ) { Object menu = it.next(); copyMenuProperties (menu, getDesignTime(menu)); } } }); } Object getDesignTime (Object awtMenu) { Object swingMenu = designTimeMenus.get(awtMenu); if (swingMenu == null) { // create swingMenu with copy of awtMenu aplicable properties switch (recognizeType (awtMenu.getClass())) { case T_MENUBAR: swingMenu = new JMenuBar (); break; case T_MENU: swingMenu = new JMenu (); break; case T_POPUPMENU: swingMenu = new JPopupMenu (); break; case T_MENUITEM: swingMenu = new JMenuItem (); break; case T_CHECKBOXMENUITEM: swingMenu = new JCheckBoxMenuItem (); break; case T_JMENUBAR: case T_JMENU: case T_JPOPUPMENU: case T_JMENUITEM: case T_JCHECKBOXMENUITEM: case T_JRADIOBUTTONMENUITEM: case T_JSEPARATOR: swingMenu = awtMenu; break; // PENDING - T_SEPARATOR } designTimeMenus.put (awtMenu, swingMenu); copyMenuProperties (awtMenu, swingMenu); } return swingMenu; } // copy all aplicable properties into swing equivalent of awt component void copyMenuProperties (Object awtMenu, Object swingMenu) { switch (recognizeType (awtMenu.getClass())) { case T_MENUBAR: MenuBar mb = (MenuBar) awtMenu; JMenuBar jmb = (JMenuBar) swingMenu; jmb.setFont(mb.getFont()); jmb.setName(mb.getName()); break; case T_MENU: Menu m = (Menu) awtMenu; JMenu jm = (JMenu) swingMenu; jm.setActionCommand(m.getActionCommand()); jm.setEnabled(m.isEnabled()); jm.setFont(m.getFont()); jm.setLabel(m.getLabel()); jm.setName(m.getName()); jm.getPopupMenu().setLightWeightPopupEnabled(false); break; case T_POPUPMENU: PopupMenu pm = (PopupMenu) awtMenu; JPopupMenu jpm = (JPopupMenu) swingMenu; jpm.setEnabled(pm.isEnabled()); jpm.setFont(pm.getFont()); jpm.setLabel(pm.getLabel()); jpm.setName(pm.getName()); jpm.setLightWeightPopupEnabled(false); break; case T_MENUITEM: MenuItem mi = (MenuItem) awtMenu; JMenuItem jmi = (JMenuItem) swingMenu; jmi.setActionCommand(mi.getActionCommand()); jmi.setEnabled(mi.isEnabled()); jmi.setFont(mi.getFont()); jmi.setLabel(mi.getLabel()); jmi.setName(mi.getName()); break; case T_CHECKBOXMENUITEM: CheckboxMenuItem cm = (CheckboxMenuItem) awtMenu; JCheckBoxMenuItem jcm = (JCheckBoxMenuItem) swingMenu; jcm.setActionCommand(cm.getActionCommand()); jcm.setEnabled(cm.isEnabled()); jcm.setFont(cm.getFont()); jcm.setLabel(cm.getLabel()); jcm.setName (cm.getName()); jcm.setState(cm.getState()); break; // PENDING - T_SEPARATOR } } } } /* * Log * 10 Gandalf-post-FCS1.8.1.0 3/27/00 Tran Duc Trung FIX #6021: cannot add * AWT PopMenu * 9 Gandalf 1.8 1/5/00 Ian Formanek NOI18N * 8 Gandalf 1.7 12/2/99 Pavel Buzek AWT menu is displayed in * form at design time (a swing equivalent is created for each awt menu * and displyed instead) * 7 Gandalf 1.6 11/10/99 Pavel Buzek while menu is selectedf * in form in test mode do not go to event handler * 6 Gandalf 1.5 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 5 Gandalf 1.4 10/9/99 Ian Formanek Fixed bug 4411 - Delete * of a jMenuItem does not work. (No action is performed.) * 4 Gandalf 1.3 9/6/99 Ian Formanek Correctly works with * separators - fixes bug 3703 - When a new separator is created usng New * > Separator in a menu, an exception is thrown. * 3 Gandalf 1.2 8/6/99 Ian Formanek setComponent is public * 2 Gandalf 1.1 7/16/99 Ian Formanek default action * 1 Gandalf 1.0 7/5/99 Ian Formanek * $ */